package com.ue.simple_calculator.widget;

import android.content.Context;
import android.support.annotation.AttrRes;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.FrameLayout;

import com.ue.simple_calculator.R;
import com.ue.simple_calculator.util.Calculator;


/**
 * Created by hujiang on 2017/3/22.
 */

public class CalcPanel extends FrameLayout {
    private String formulaTxt = "";
    private String resultTxt = "";

    private OnCalcResultListener onCalcResultListener;

    public CalcPanel(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public CalcPanel(@NonNull Context context, @Nullable AttributeSet attrs, @AttrRes int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        LayoutInflater.from(context).inflate(R.layout.layout_calc_panel, this);
        OnClickListener onClickListener = new OnClickListener() {
            @Override
            public void onClick(View view) {
                if (null == onCalcResultListener) {
                    return;
                }
                int viewId = view.getId();
                switch (viewId) {
                    case R.id.tv_num7:
                        onNumberClick(7);
                        break;
                    case R.id.tv_num8:
                        onNumberClick(8);
                        break;
                    case R.id.tv_num9:
                        onNumberClick(9);
                        break;
                    case R.id.tv_op_add:
                        onOpClick("+");
                        break;
                    case R.id.tv_num4:
                        onNumberClick(4);
                        break;
                    case R.id.tv_num5:
                        onNumberClick(5);
                        break;
                    case R.id.tv_num6:
                        onNumberClick(6);
                        break;
                    case R.id.tv_op_sub:
                        onOpClick("-");
                        break;
                    case R.id.tv_num1:
                        onNumberClick(1);
                        break;
                    case R.id.tv_num2:
                        onNumberClick(2);
                        break;
                    case R.id.tv_num3:
                        onNumberClick(3);
                        break;
                    case R.id.tv_op_multi:
                        onOpClick("×");
                        break;
                    case R.id.tv_num_point:
                        onPointClick();
                        break;
                    case R.id.tv_num0:
                        onNumberClick(0);
                        break;
                    case R.id.iv_delete_num:
                        onDelClick();
                        break;
                    case R.id.tv_op_divide:
                        onOpClick("÷");
                        break;
                }
            }
        };

        findViewById(R.id.tv_num7).setOnClickListener(onClickListener);
        findViewById(R.id.tv_num8).setOnClickListener(onClickListener);
        findViewById(R.id.tv_num9).setOnClickListener(onClickListener);
        findViewById(R.id.tv_op_add).setOnClickListener(onClickListener);
        findViewById(R.id.tv_num4).setOnClickListener(onClickListener);
        findViewById(R.id.tv_num5).setOnClickListener(onClickListener);
        findViewById(R.id.tv_num6).setOnClickListener(onClickListener);
        findViewById(R.id.tv_op_sub).setOnClickListener(onClickListener);
        findViewById(R.id.tv_num1).setOnClickListener(onClickListener);
        findViewById(R.id.tv_num2).setOnClickListener(onClickListener);
        findViewById(R.id.tv_num3).setOnClickListener(onClickListener);
        findViewById(R.id.tv_op_multi).setOnClickListener(onClickListener);
        findViewById(R.id.tv_num_point).setOnClickListener(onClickListener);
        findViewById(R.id.tv_num0).setOnClickListener(onClickListener);
        findViewById(R.id.iv_delete_num).setOnClickListener(onClickListener);
        findViewById(R.id.tv_op_divide).setOnClickListener(onClickListener);
    }

    private void onPointClick() {
        if (TextUtils.isEmpty(formulaTxt)) {
            if (TextUtils.isEmpty(resultTxt)) {
                resultTxt = "0.";
                onCalcResultListener.onCalcResult(formulaTxt, resultTxt);
                return;
            }
            if (isOpCode(resultTxt.charAt(resultTxt.length() - 1))) {
                return;
            }
            resultTxt = resultTxt + ".";
            onCalcResultListener.onCalcResult(formulaTxt, resultTxt);
            return;
        }
        if (isOpCode(formulaTxt.charAt(formulaTxt.length() - 1))) {
            return;
        }
        formulaTxt = formulaTxt + ".";
        onCalcResultListener.onCalcResult(formulaTxt, resultTxt);
    }

    private void onDelClick() {
        if (TextUtils.isEmpty(formulaTxt) && TextUtils.isEmpty(resultTxt)) {
            return;
        }
        if (TextUtils.isEmpty(formulaTxt)) {
            if (resultTxt.equals(".0")) {
                resultTxt = "";
                onCalcResultListener.onCalcResult(formulaTxt, resultTxt);
                return;
            }
            resultTxt = resultTxt.substring(0, resultTxt.length() - 1);
            onCalcResultListener.onCalcResult(formulaTxt, resultTxt);
            return;
        }
        formulaTxt = formulaTxt.substring(0, formulaTxt.length() - 1);
        calc();
    }

    private void onNumberClick(int number) {
        if (TextUtils.isEmpty(formulaTxt)) {
            resultTxt = resultTxt + number;
            onCalcResultListener.onCalcResult(formulaTxt, resultTxt);
        } else {
            formulaTxt = formulaTxt + number;
            calc();
        }
    }

    private void onOpClick(String opCode) {
        //判断表达式或结果最后一位是否是运算符
        if (TextUtils.isEmpty(formulaTxt)) {
            if (TextUtils.isEmpty(resultTxt)) {
                return;
            }
            //避免formulaTxt="1.+(-×÷)"的情况
            if(resultTxt.charAt(resultTxt.length()-1)=='.'){
                return;
            }
            formulaTxt = resultTxt;
        } else {
            if (isOpCode(formulaTxt.charAt(formulaTxt.length() - 1))) {
                return;
            }
        }
        formulaTxt = formulaTxt + opCode;
        calc();
    }

    private void calc() {
        if (TextUtils.isEmpty(formulaTxt)) {
            resultTxt = "";
            onCalcResultListener.onCalcResult(formulaTxt, resultTxt);
            return;
        }
        String tempTxt = formulaTxt;
        //如果最后一位是符号，去除
        char lastChar = tempTxt.charAt(tempTxt.length() - 1);
        if (isOpCode(lastChar)) {
            tempTxt = tempTxt.substring(0, tempTxt.length() - 1);
        }
        //替换乘除号为电脑运算符号
        tempTxt = tempTxt.replace("×", "*").replace("÷", "/");
        double resultNum = Calculator.conversion(tempTxt);
        resultTxt = String.valueOf(resultNum);

        onCalcResultListener.onCalcResult(formulaTxt, resultTxt);
    }

    public boolean isOpCode(char lastChar) {
        return lastChar == '+' || lastChar == '-' || lastChar == '×' || lastChar == '÷' || lastChar == '.';
    }

    public void reset() {
        formulaTxt = "";
        resultTxt = "";
    }


    public void setOnCalcResultListener(OnCalcResultListener onCalcResultListener) {
        this.onCalcResultListener = onCalcResultListener;
    }

    public interface OnCalcResultListener {
        void onCalcResult(String formulaTxt, String result);
    }
}
